<?php

namespace think\response;

use think\Collection;
use think\Model;
use think\Response;

/**
 * Krpano解析
 * 
 * @author 陈黎明 <19536238@qq.com>
 * @since     2018-4-24
 * 
 */
class Krpano extends Response {

    // 输出参数
    protected $options = [
        // 根节点名
        'root_node' => 'krpano',
        // 根节点属性
        'root_attr' => '',
        //数字索引的子节点名
        'item_node' => 'item',
        // 数字索引子节点key转换的属性名
        'item_key' => 'id',
        // 数据编码
        'encoding' => 'utf-8',
        'is_root' => true,
        'is_xml' => false,
    ];
    protected $contentType = 'text/xml';

    /**
     * 输出xml方式
     * @access protected
     * @param mixed $data 要处理的数据
     * @return mixed
     */
    public function output_xml($data, $is_root = true, $is_xml = false) {
        $this->options['is_root'] = $is_root;
        $this->options['is_xml'] = $is_xml;
        // XML数据转换
        return $this->xmlEncode($data, $this->options['root_node'], $this->options['item_node'], $this->options['root_attr'], $this->options['item_key'], $this->options['encoding'], $this->options['is_root'], $this->options['is_xml']);
    }

    /**
     * 处理数据
     * @access protected
     * @param mixed $data 要处理的数据
     * @return mixed 
     */
    protected function output($data) {
        // XML数据转换
        return $this->xmlEncode($data, $this->options['root_node'], $this->options['item_node'], $this->options['root_attr'], $this->options['item_key'], $this->options['encoding'], $this->options['is_root'], $this->options['is_xml']);
    }

    /**
     * XML编码
     * @param mixed $data 数据
     * @param string $root 根节点名
     * @param string $item 数字索引的子节点名
     * @param string $attr 根节点属性
     * @param string $id   数字索引子节点key转换的属性名
     * @param string $encoding 数据编码
     * @return string
     */
    protected function xmlEncode($data, $root, $item, $attr, $id, $encoding, $is_root = true, $is_xml = false) {
        if (is_array($attr)) {
            $array = [];
            foreach ($attr as $key => $value) {
                $array[] = "{$key}=\"{$value}\"";
            }
            $attr = implode(' ', $array);
        }
        $attr = trim($attr);
        $attr = empty($attr) ? '' : " {$attr}";

        $xml = $is_xml ? '' : "<?xml version=\"1.0\" encoding=\"{$encoding}\"?>";


        if ($is_root === true) {
            $xml .= "<{$root}{$attr}>";
        }
        $xml .= $this->dataToXml($data, $item, $id);
        if ($is_root === true) {
            $xml .= "</{$root}>";
        }

        return $xml;
    }

    /**
     * 属性编码
     * @param mixed  $data 数据
     * @param string $item 数字索引时的节点名称
     * @param string $id   数字索引key转换为的属性名
     * @return string
     */
    protected function ToAttr($data) {
        $xml = $_attr = '';
        $vol = json_decode($data, true);
        foreach ($vol as $k => $v) {
            // 具体内容项
            $_attr = ' ' . $k . '="' . $v . '"';
            $xml .= $_attr;
        }
        return $xml;
    }

    /**
     * 数据XML编码
     * @param mixed  $data 数据
     * @param string $item 数字索引时的节点名称
     * @param string $id   数字索引key转换为的属性名
     * @return string
     */
    protected function dataToXml($data, $item, $id) {
        $xml = $attr = '';

        if ($data instanceof Collection || $data instanceof Model) {
            $data = $data->toArray();
        }
//        var_dump($data);exit;
        foreach ($data as $key => $val) {
            // key,不能为纯数字
            if (is_numeric($key)) {
                $id && $attr = " {$id}=\"{$key}\"";
                $key = $item;
            }
//            var_dump($val['attr']);exit;
            // 先把attr剔除掉
            if (isset($val['attr'])) {
                $attr = $this->ToAttr($val['attr']);
                unset($val['attr']);
            }
//            var_dump($data);exit;

            if (is_array($val) || is_object($val)) {
                $xml .= "<{$key}{$attr}>";
                $xml .= $this->dataToXml($val, $item, $id);
                $xml .= "</{$key}>";
            } elseif (is_json($val)) {
                if ($key != 'item') {
                    $xml .= "<{$key}{$attr}>";
                }

                $vol = json_decode($val, true);
                foreach ($vol as $k => $v) {
                    $_root = $v;
                    // 具体内容项
                    $_attr = '';
                    foreach ($_root as $m => $n) {
                        $_attr .= ' ' . $m . '="' . $n . '"';
                    }
                    $xml .= "<{$k}{$_attr}/>";
                }
                if ($key != 'item') {
                    $xml .= "</{$key}>";
                }
            } elseif ($key = 'item') {
                if (is_json($val)) {
                    $this->dataToXml($val, $item, $id);
                }
            } elseif (is_string($val)) {
                
            } else {
                $xml .= "<{$key}{$attr}>";
                $xml .= $val;
                $xml .= "</{$key}>";
            }
        }
        return $xml;
    }

}
